const axios = require('axios')
const fs = require('fs')
const path = require('path')
const parseUrl = require('url').parse
const fse = require('fs-extra')
// const throttle = require('throttleit');
const dayjs = require('dayjs')

/**
 * 动态目录
 */
function dynamicFilePath() {
  return `/uploads/` + dayjs().format('YYMMDD') + '/'
}

/**
 * 动态文件名
 */
function dynamicFileName() {
  return dayjs().format('HHmmss') + Math.random().toString().substr(2, 5)
}

/**
 * 下载
 * @param {*} url
 * @param {*} filePath
 * @param {*} fileName
 */
async function download(url, options = {}) {
  options = {
    fileDir: __dirname,
    fileName: decodeURIComponent(parseUrl(url).pathname.split('/').pop()),
    downloadProgress() {},
    // 断点续传
    _continue: false,
    // 临时文件
    temp: true,
    // 动态文件名
    dynamicName: false,
    // 动态目录
    dynamicPath: false,
    ...options,
  }

  const suffix = '.' + url.split('.').pop().split('?')[0]

  let { fileDir, fileName, downloadProgress, _continue, dynamicName, dynamicPath } = options

  // 动态目录
  if (dynamicPath) {
    fileDir = path.join(__dirname, dynamicFilePath())
  }

  // 动态文件名
  if (dynamicName) {
    fileName = dynamicFileName() + suffix
  }

  // 自动添加文件后缀
  if (suffix && fileName.indexOf('.') == 1) {
    fileName += suffix
  }

  // 下载的文件完整路径
  let savePath = path.join(fileDir, fileName)

  // 判断是否需要创建下载目录
  fse.ensureDirSync(fileDir)

  // 输出流
  let writer

  // 临时命名
  let temp

  // 重零下载
  if (!fs.existsSync(savePath) || !_continue) {
    if (temp) savePath += '.temp'

    writer = fs.createWriteStream(savePath, {})
  }
  // 续传
  else {
    stat = fs.statSync(savePath)
    transferred = stat.size
    writer = fs.createWriteStream(savePath, {
      flags: 'r+',
      start: transferred,
    })
  }

  const response = await axios({
    url,
    method: 'GET',
    responseType: 'stream',
    onDownloadProgress: (progressEvent) => {
      console.log('progressEvent', progressEvent)
    },
  })

  response.data.pipe(writer)

  const totalSize = response.headers['content-length']
  let downloaded = 0
  let transferred = 0
  let tempTransferred = 0

  response.data.on('data', (data) => {
    downloaded += Buffer.byteLength(data)
    downloadProgress({ total: totalSize, loaded: downloaded })
  })

  response.data.on('end', () => {})

  response.data.on('error', (error) => {})

  return new Promise((resolve, reject) => {
    writer.on('finish', () => {
      if (temp) {
        fse.moveSync(savePath, savePath.replace('.temp', ''), {
          overwrite: true,
        })
      }

      resolve({
        fileName,
        savePath,
      })
    })
    writer.on('error', reject)
  })
}

module.exports = download
